// auth.service.ts
// 引入加密库 crypto-js，用于数据加密和解密
import CryptoJS from 'crypto-js'

// 定义加密密钥，使用 Vue 项目中的环境变量访问方式

const SECRET_KEY = 'your-secret-key'

// 导出认证服务类
export class AuthService {
    // 定义存储token的键名
    private readonly TOKEN_KEY = 'auth_token'
    // 定义存储用户信息的键名
    private readonly USER_KEY = 'user_data'
    // 定义存储用户ID的键名
    private readonly USER_ID_KEY = 'user_id'

    // 加密数据的私有方法
    // 接收明文字符串，返回使用AES算法加密后的密文
    private encrypt(data: string): string {
        return CryptoJS.AES.encrypt(data, SECRET_KEY).toString()
    }

    // 解密数据的私有方法
    // 接收密文字符串，返回解密后的明文
    private decrypt(encryptedData: string): string {
        const bytes = CryptoJS.AES.decrypt(encryptedData, SECRET_KEY)
        return bytes.toString(CryptoJS.enc.Utf8)
    }

    // 存储认证信息（token和用户信息）的公共方法
    // 参数：token - 认证令牌，user - 用户对象，rememberMe - 是否记住用户（决定存储方式）
    public setAuth(token: string, user: object, rememberMe: boolean = false): void {
        // 将用户信息转换为JSON字符串并加密
        const encryptedUser = this.encrypt(JSON.stringify(user))

        // 提取用户ID（假设用户对象中有id字段）
        const userId = (user as any).id

        // 根据rememberMe参数决定存储方式：
        // 如果为true，则使用localStorage进行长期存储（即使关闭浏览器也不会丢失）
        if (rememberMe) {
            localStorage.setItem(this.TOKEN_KEY, token)
            localStorage.setItem(this.USER_KEY, encryptedUser)
            if (userId) {
                localStorage.setItem(this.USER_ID_KEY, userId.toString())
            }
        }
        // 如果为false，则使用sessionStorage进行会话存储（关闭浏览器后丢失）
        else {
            sessionStorage.setItem(this.TOKEN_KEY, token)
            sessionStorage.setItem(this.USER_KEY, encryptedUser)
            if (userId) {
                sessionStorage.setItem(this.USER_ID_KEY, userId.toString())
            }
        }
    }

    // 获取认证token的公共方法
    // 优先从localStorage中获取，如果没有则从sessionStorage中获取
    public getToken(): string | null {
        return localStorage.getItem(this.TOKEN_KEY) || sessionStorage.getItem(this.TOKEN_KEY)
    }

    // 获取用户信息的公共方法
    // 从存储中获取加密的用户数据，解密后转换为对象返回
    public getUser(): any | null {
        // 从localStorage或sessionStorage中获取加密的用户数据
        const userData = localStorage.getItem(this.USER_KEY) || sessionStorage.getItem(this.USER_KEY)
        // 如果存在用户数据，则解密并解析为对象，否则返回null
        return userData ? JSON.parse(this.decrypt(userData)) : null
    }

    // 获取用户ID的公共方法
    public getUserId(): string | null {
        return localStorage.getItem(this.USER_ID_KEY) || sessionStorage.getItem(this.USER_ID_KEY)
    }

    // 清除所有认证信息的公共方法
    // 删除localStorage和sessionStorage中的token和用户信息
    public clearAuth(): void {
        localStorage.removeItem(this.TOKEN_KEY)
        localStorage.removeItem(this.USER_KEY)
        localStorage.removeItem(this.USER_ID_KEY)
        sessionStorage.removeItem(this.TOKEN_KEY)
        sessionStorage.removeItem(this.USER_KEY)
        sessionStorage.removeItem(this.USER_ID_KEY)
    }
}
